package com.jee.ssm.modules.user.app;

import java.io.File;
import java.math.BigDecimal;
import java.text.ParseException;
import java.util.Date;
import java.util.List;
import java.util.regex.Pattern;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.DisabledAccountException;
import org.apache.shiro.authc.ExcessiveAttemptsException;
import org.apache.shiro.authc.ExpiredCredentialsException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.UnauthorizedException;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import com.jee.ssm.common.config.Const;
import com.jee.ssm.common.shiro.ShiroAccount;
import com.jee.ssm.common.utils.RandomNumberUtils;
import com.jee.ssm.common.utils.SmUtils;
import com.jee.ssm.common.utils.TimeUtils;
import com.jee.ssm.common.utils.TokenUtils;
import com.jee.ssm.common.utils.UUIDFactory;
import com.jee.ssm.model.Account;
import com.jee.ssm.model.SmRecord;
import com.jee.ssm.model.User;
import com.jee.ssm.model.json.Tip;
import com.jee.ssm.modules.personalMessage.services.PersonalMessageService;
import com.jee.ssm.modules.smRecord.services.SmRecordService;
import com.jee.ssm.modules.ssm.services.AccountService;
import com.jee.ssm.modules.user.services.UserService;
import com.jee.ssm.modules.userPlate.services.UserPlateService;

/**
* 注册用户管理 客户端 Controller
* @author GaoXiang
* @version 1.0
*/
@Controller
@RequestMapping("/app/user")
public class AppUserController {
	
	/**
     * 校验手机号
     * 
     * @param mobile
     * @return 校验通过返回true，否则返回false
     */
    public static boolean isMobile(String mobile) {
        return Pattern.matches(Const.REGEX_MOBILE, mobile);
    }

    @RequestMapping(value = "/getVerifyCode")
    @ResponseBody
    public Tip getVerifyCode(String phone, String type, long timestamp, String token) {
        Tip tip = TokenUtils.verifyToken(timestamp, token);
        if(tip.getSuccess()) {
        	if(phone != null && !"".equals(phone)) {
        		List<User> list = userService.findByPhone(phone);
                if("1".equals(type)){	//1:用户注册
                    if(list.size() == 0) {
                        tip = sendSm(phone, RandomNumberUtils.get6Number(), "用户注册");
                    } else {
                        tip = new Tip(2, "该手机号码已被注册");
                    }
                } else if("2".equals(type)) {	//2:修改手机号码
                    if(list.size() == 0) {
                        tip = sendSm(phone, RandomNumberUtils.get6Number(), "修改手机号码");
                    } else {
                        tip = new Tip(2, "该手机号码已被注册");
                    }
                } else if("3".equals(type)) {	//3:找回密码
                    if(list.size() == 1) {
                        tip = sendSm(phone, RandomNumberUtils.get6Number(), "找回密码");
                    } else {
                        tip = new Tip(2, "该手机号码未被注册");
                    }
                } else if("4".equals(type)) {	//4:修改支付密码
                    if(list.size() == 1) {
                        tip = sendSm(phone, RandomNumberUtils.get6Number(), "设置支付密码");
                    } else {
                        tip = new Tip(2, "该手机号码未被注册");
                    }
                } else {
                    tip = new Tip(3, "状态类型异常，请刷新重试");
                }
        	} else {
        		tip = new Tip(4, "请输入正确的手机号码");
        	}
        }
        return tip;
    }

    @RequestMapping(value = "/register")
    @ResponseBody
    public Tip register(String phone, String password, String verifyCode, long timestamp, String token) {
        Tip tip = TokenUtils.verifyToken(timestamp, token);
        if(tip.getSuccess()) {
        	SmRecord sr = new SmRecord(phone, "用户注册");
            List<SmRecord> list = smRecordService.findByPhone(sr);
            if(list.size() > 0) {
                SmRecord s = list.get(0);
                if(verifyCode.equals(s.getVerifyCode())) {
                    if((System.currentTimeMillis() - s.getCreateTime().getTime()) <= 300000) {
                    	
                    	List<User> users = userService.findByPhone(phone);
                        if(users.size() == 0) {
                        	String userId = UUIDFactory.getStringId();
                            Account account = new Account(UUIDFactory.getStringId(), phone, password, 2, 1, userId);
                            User user = new User(userId, "sdhr_" + phone.substring(5, 11), null, null, null, 2, null, null, phone, 1, 1, null, new Date(), new Date(), null, BigDecimal.valueOf(0), BigDecimal.valueOf(0), null);
                            try {
                                userService.register(account, user);
                                tip = new Tip("注册成功", user);
                            } catch (Exception e) {
                                e.printStackTrace();
                                tip = new Tip(2, "系统异常，注册失败");
                            }
                        } else {
                            tip = new Tip(5, "该手机号码已被注册");
                        }
                        
                    } else {
                        tip = new Tip(4, "验证码超时，请重新点击发送");
                    }

                } else {
                    tip = new Tip(3, "验证码不正确");
                }
            } else {
                tip = new Tip(1, "验证码不正确");
            }
        }
        return tip;
    }

    @RequestMapping(value = "/login")
    @ResponseBody
    public Tip login(String phone, String password, long timestamp, String token) {
        Tip tip = TokenUtils.verifyToken(timestamp, token);
        if(tip.getSuccess()) {
            //获取当前会话主体
            Subject subject = SecurityUtils.getSubject();

            //获取token
            UsernamePasswordToken t = new UsernamePasswordToken(phone, password);

            try {
                //登录
                subject.login(t);

                //如果登录成功
                if (subject.isAuthenticated()) {

                    ShiroAccount shiroAccount = (ShiroAccount) subject.getPrincipal();

                    Account dba = shiroAccount.getAccount();

                    User user = userService.selectById(dba.getInfoId());
                    
                    user.setUnread(personalMessageService.findUnreadNumByUserId(user.getId()));

                    tip = new Tip("登录成功", user);
                }

            } catch (IncorrectCredentialsException e) {
                tip = new Tip(11, "登录密码错误！");
            } catch (ExcessiveAttemptsException e) {
                tip =  new Tip(12, "登录失败次数过多！");
            } catch (LockedAccountException e) {
                tip = new Tip(13, "帐号已被锁定！");
            } catch (DisabledAccountException e) {
                tip = new Tip(14, "帐号已被禁用！");
            } catch (ExpiredCredentialsException e) {
                tip = new Tip(15, "帐号已过期！");
            } catch (UnknownAccountException e) {
                tip = new Tip(16, "帐号不存在！");
            } catch (UnauthorizedException e) {
                tip = new Tip(17, "您没有得到相应的授权！");
            } catch(Exception e) {
            	tip = new Tip(18, "账号异常，请联系后台管理员");
            }
        }
        return tip;
    }

    /**
     * 查询余额
     * @param timestamp 查询时间
     * @param token 令牌
     * @param userId 用户id
     * @return
     */
    @RequestMapping(value = "/findBalanceByUserId", method = RequestMethod.GET)
    @ResponseBody
    public Tip findBalanceByUserId(long timestamp, String token, String userId) {
        Tip tip = TokenUtils.verifyToken(timestamp, token);
        if(tip.getSuccess()) {
            User user = userService.selectById(userId);
            tip.setData(user.getWalletBalance());
        }
        return tip;
    }

    private Tip sendSm(String phone, String verifyCode, String type) {
        Tip tip = new Tip("发送成功");
        String verifyContent = "您的验证码是：" + verifyCode + "【约慧夏都】";
        //发送短信验证码
        String id = UUIDFactory.getStringId();
        SmRecord s = new SmRecord(id, phone, new Date(), verifyCode, verifyContent, type, "发送失败");
        try {
            smRecordService.insert(s);
            smUtils.send(id, phone, verifyContent);
        } catch (Exception e){
            tip = new Tip(2, "系统异常，发送失败");
        }
        return tip;
    }
    
    @RequestMapping(value = "/editUserHeadImg", method = RequestMethod.POST)
    @ResponseBody
    public Tip editUserHeadImg(HttpServletRequest request, long timestamp, String token, String userId, MultipartFile file) {
    	Tip tip = TokenUtils.verifyToken(timestamp, token);
    	if(tip.getSuccess()) {
    		User user = new User();
    		user.setId(userId);
    		if(file != null) {
    			String url = "/images/head-img/" + userId + "/";
    			String path = request.getServletContext().getRealPath(url);
    			File d = new File(path);
    			if(!d.exists() && !d.isDirectory()) {
    				d.mkdirs();
    			}
    			String fileName = userId + "_" + System.currentTimeMillis() + ".jpg";
    			path = path + fileName;
    			File headImg = new File(path);
    			try {
					file.transferTo(headImg);
					user.setHeadImage(url + fileName);
					userService.updateById(user);
					tip = new Tip("头像修改成功");
				} catch (Exception e) {
					tip = new Tip(2, "系统异常，头像修改失败，请重试");
				}
    		} else {
    			tip = new Tip(1, "请上传图片");
    		}
    	}
    	return tip;
    }


    @RequestMapping(value = "/editUserInfo", method = RequestMethod.POST)
    @ResponseBody
    public Tip editUserInfo(long timestamp, String token, String userId,String userName, String sex, String birthDay) {
    	Tip tip = TokenUtils.verifyToken(timestamp, token);
    	if(tip.getSuccess()) {
    		User user = new User();
    		user.setId(userId);
    		if(sex != null && !"".equals(sex)) {
    			user.setSex(Integer.valueOf(sex));
    		}
    		if (userName !=null && !"".equals(userName)){
    		    user.setName(userName);
            }
    		try {
    			if(birthDay != null && !"".equals(birthDay)) {
    				user.setBirthTime(TimeUtils.getDateByYear(birthDay));
        		}
    			user.setUpdateTime(new Date());
				userService.updateById(user);
				tip = new Tip("修改成功");
			} catch (ParseException e) {
				tip = new Tip(2, "日期格式不正确");
			} catch (Exception e) {
				tip = new Tip(1, "系统异常，修改失败，请刷新重试");
			}
    		
    	}
    	return tip;
    }

    /**
     * 修改手机号码
     * @param timestamp
     * @param token
     * @param userId
     * @param phone
     * @param verifyCode
     * @return
     */
    @RequestMapping(value = "/editPhoneByUserId", method = RequestMethod.GET)
    @ResponseBody
    public Tip editPhoneByUserId(long timestamp, String token, String userId, String phone, String verifyCode) {
    	Tip tip = TokenUtils.verifyToken(timestamp, token);
    	if(tip.getSuccess()) {
    		SmRecord sr = new SmRecord(phone, "修改手机号码");
            List<SmRecord> list = smRecordService.findByPhone(sr);
            if(list.size() > 0) {
                SmRecord s = list.get(0);
                if(verifyCode.equals(s.getVerifyCode())) {
                    if((System.currentTimeMillis() - s.getCreateTime().getTime()) <= 300000) {
                        Account account = new Account(phone, userId);
                        User user = new User(userId, phone);
                        try {
                            userService.editPhoneByUserId(account, user);
                            tip = new Tip("手机号码修改成功");
                        } catch (Exception e) {
                            e.printStackTrace();
                            tip = new Tip(2, "系统异常，修改失败，请稍后重试");
                        }
                    } else {
                        tip = new Tip(4, "验证码超时，请重新点击发送");
                    }

                } else {
                    tip = new Tip(3, "验证码不正确");
                }
            } else {
                tip = new Tip(3, "验证码不正确");
            }
    	}
    	return tip;
    }
    
    @RequestMapping(value = "/editPasswordByPhone", method = RequestMethod.GET)
    @ResponseBody
    public Tip editPasswordByPhone(long timestamp, String token, String phone, String password, String verifyCode) {
    	Tip tip = TokenUtils.verifyToken(timestamp, token);
    	if(tip.getSuccess()) {
    		SmRecord sr = new SmRecord(phone, "找回密码");
            List<SmRecord> list = smRecordService.findByPhone(sr);
            if(list.size() > 0) {
                SmRecord s = list.get(0);
                if(verifyCode.equals(s.getVerifyCode())) {
                    if((System.currentTimeMillis() - s.getCreateTime().getTime()) <= 300000) {
                        Account account = new Account();
                        account.setUserName(phone);
                        account.setPassword(password);
                        try {
                            userService.editPasswordByUserName(account);
                            tip = new Tip("修改密码成功");
                        } catch (Exception e) {
                            e.printStackTrace();
                            tip = new Tip(2, "系统异常，修改失败，请稍后重试");
                        }
                    } else {
                        tip = new Tip(4, "验证码超时，请重新点击发送");
                    }

                } else {
                    tip = new Tip(3, "验证码不正确");
                }
            } else {
                tip = new Tip(3, "验证码不正确");
            }
    	}
    	return tip;
    }
    
    /**
     * 修改登录密码
     * @param userId
     * @param password 新密码
     * @return 成功失败的提示
     */
    @RequestMapping(value = "/editAccountPassWord", method = RequestMethod.GET)
    @ResponseBody
    public Tip  editAccountPassWord(long timestamp, String token, String userId, String password) {
    	Tip tip = TokenUtils.verifyToken(timestamp, token);
    	if(tip.getSuccess()) {
    		User user = userService.selectById(userId);
    		if(user != null) {
    			Account account = accountService.findByInfoId(user.getId());
    			if(account != null) {
    				account.setPassword(password);
    				try {
						accountService.updateById(account);
						tip = new Tip("修改成功");
					} catch (Exception e) {
						e.printStackTrace();
						tip = new Tip(3, "系统异常，请刷新重试");
					}
    			} else {
    				tip = new Tip(2, "系统异常，请联系客服");
    			}
    		} else {
    			tip = new Tip(1, "用户信息失效，请重新登录");
    		}
    	}
    	return tip;
    }
    
    /**
     * 修改支付密码前的手机验证
     * @param userId 用户标识
     * @param phone 手机号码
     * @param verifyCode 验证码
     * @return 验证成功
     */
    @RequestMapping(value = "/validatePayPasswordCode", method = RequestMethod.GET)
    @ResponseBody
    public Tip validatePayPasswordCode(long timestamp, String token, String userId, String phone, String verifyCode) {
    	Tip tip = TokenUtils.verifyToken(timestamp, token);
    	if(tip.getSuccess()) {
    		User user = userService.selectById(userId);
    		if(user != null) {
    			SmRecord sr = new SmRecord(phone, "设置支付密码");
                List<SmRecord> list = smRecordService.findByPhone(sr);
                if(list.size() > 0) {
                	SmRecord s = list.get(0);
                	if(verifyCode.equals(s.getVerifyCode())) {
                		if((System.currentTimeMillis() - s.getCreateTime().getTime()) <= 300000) {
                			tip = new Tip("验证码正确");
                		} else {
                            tip = new Tip(2, "验证码超时，请重新点击发送");
                        }
                	} else {
                        tip = new Tip(3, "验证码不正确");
                    }
                } else {
                    tip = new Tip(3, "验证码不正确");
                }
    		} else {
    			tip = new Tip(1, "用户信息失效，请重新登录");
    		}
    	}
    	return tip;
    }
    
    /**
     * 设置支付密码
     * @param userId 用户标识
     * @param payPassword 支付密码（加密后）
     * @return 成功提示
     */
    @RequestMapping(value = "/editPayPassword", method = RequestMethod.GET)
    @ResponseBody
    public Tip editPayPassword(long timestamp, String token, String userId, String payPassword) {
    	Tip tip = TokenUtils.verifyToken(timestamp, token);
    	if(tip.getSuccess()) {
    		User user = userService.selectById(userId);
    		if(user != null) {
        		user.setPayPassword(payPassword);
    			try {
					userService.updateById(user);
					tip = new Tip("设置成功");
				} catch (Exception e) {
					e.printStackTrace();
					tip = new Tip(2, "系统异常，请刷新重试");
				}
    		} else {
    			tip = new Tip(1, "用户信息失效，请重新登录");
    		}
    	}
    	return tip;
    }
    
    /**
     * 验证支付密码
     * @param userId 用户id
     * @param payPassword 支付密码（加密后）
     * @return
     */
    @RequestMapping(value = "/validatePayPassword", method = RequestMethod.GET)
    @ResponseBody
    public Tip validatePayPassword(long timestamp, String token, String userId, String payPassword) {
    	Tip tip = TokenUtils.verifyToken(timestamp, token);
    	if(tip.getSuccess()) {
    		User user = userService.selectById(userId);
    		if(user != null) {
    			if(payPassword.equals(user.getPayPassword())) {
    				tip = new Tip("密码正确");
    			} else  {
    				tip = new Tip(2, "密码错误");
    			}
    		} else {
    			tip = new Tip(1, "用户信息失效，请重新登录");
    		}
    	}
    	return tip;
    }


    //---------------------------- property -------------------------------

    @Resource
    private UserService userService;

    @Resource
    private SmUtils smUtils;

    @Resource
    private SmRecordService smRecordService;

    @Resource
    private UserPlateService userPlateService;
    
    @Resource
    private AccountService accountService;
    
    @Resource
    private PersonalMessageService personalMessageService;

}
